#include "TIMER.hpp"

bool led_statu_tm = 1;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
static function_to_callback FTC[20];
static char function_callback_number = 0;
//设定分频、计数数量、定时器通道
/**
 * @brief  开启一个定时器作为伪线程,注意使用之前需要开启相关时钟
 *
 * @param  arr: 设置计时系数
 * @param  psc: 设置预分频
 * @param  Tim_bases: 设置相应计时器
 * @param  TIM_IRQn: 设置定时器中断位
 * @param  PreemptionPriority: 设置抢占优先级
 * @param  SubPriority: 设置子优先级
 * @retval None
 */
void Timer_setup::Timer_init(u16 arr, u16 psc, uint32_t Tim_bases, uint8_t TIM_IRQn, uint8_t PreemptionPriority, uint8_t SubPriority)
{
    Timer_setup::Timer_TIM_SET(arr, psc, Tim_bases);
    TIM_ClearITPendingBit((TIM_TypeDef *)Tim_bases, TIM_IT_Update);
    TIM_ITConfig((TIM_TypeDef *)Tim_bases, TIM_IT_Update, ENABLE); //开启定时器中断
    Timer_setup::Timer_TIM_NVIC(TIM_IRQn, PreemptionPriority, SubPriority);
    TIM_Cmd((TIM_TypeDef *)Tim_bases, ENABLE);
}
void Timer_setup::Timer_TIM_SET(u16 arr, u16 psc, uint32_t Tim_bases)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    TIM_TimeBaseInitStructure.TIM_Period = arr;
    TIM_TimeBaseInitStructure.TIM_Prescaler = (psc - 1);
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //滤波相关？？？？
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    // TIM_TimeBaseInitStructure.TIM_RepetitionCounter 设置显示次数
    TIM_TimeBaseInit((TIM_TypeDef *)Tim_bases, &TIM_TimeBaseInitStructure);
}
/**
 * @brief  设置定时器中断
 * @param  TIM_IRQn: 设置定时器中断位
 * @param  PreemptionPriority: 设置抢占优先级
 * @param  SubPriority: 设置子优先级
 * @retval None
 */
void Timer_setup::Timer_TIM_NVIC(uint8_t TIM_IRQn, uint8_t PreemptionPriority, uint8_t SubPriority)
{
    NVIC_InitStructure.NVIC_IRQChannel = TIM_IRQn;                             //定时器中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriority; //抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = SubPriority;               //子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                            // IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);
}
char Timer_setup::add_callback_function(void (*func)(void))
{
    FTC[function_callback_number].function_name = function_callback_number;
    FTC[function_callback_number].function_callback = func;
    function_callback_number++;
    return function_callback_number;
}
void Timer_setup::delete_callback_function(char function_number)
{
    for (int i = function_number + 1; i < function_callback_number; i++)
    {
        FTC[i].function_callback = FTC[i].function_callback;
    }
    function_callback_number--;
}
void call_back_test_func()
{
    led_statu_tm = !led_statu_tm;
    GPIO_WriteBit(GPIOB, GPIO_Pin_3, (BitAction)led_statu_tm);
}
void call_back_test_callback()
{
    Timer_setup::add_callback_function(call_back_test_func);
}
extern "C" void timer_interrupt_callback()
{
    // led_statu_tm = !led_statu_tm;
    // GPIO_WriteBit(GPIOB, GPIO_Pin_4, (BitAction)0);
    for (int i = 0; i < function_callback_number; i++)
    {
        (*FTC[i].function_callback)();
    }
}